// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;

namespace SnapObjects.Data
{
    internal class DynamicModelBaseAccessor : IModelAccessor<IDynamicModelBase>
    {
        private readonly IModelFactory<IDynamicModelBase> _factory;

        public DynamicModelBaseAccessor(
            IModelFactory<IDynamicModelBase> factory, IDynamicModelMeta modelMeta)
        {
            _factory = factory;

            this.ModelMeta = modelMeta;
        }

        public IModelMeta ModelMeta { get; }

        public int IndexOf(string name)
        {
            return this.ModelMeta.IndexOf(name);
        }

        public object GetValue(IDynamicModelBase model, int index)
        {
            return model.GetValue(index);
        }

        public object GetValue(IDynamicModelBase model, string name)
        {
            return this.IndexOf(name) >= 0 ? model.GetValue(this.IndexOf(name)) : null;
        }

        public void SetValue(IDynamicModelBase model, int index, object value)
        {
            model.SetValue(index, value);
        }

        public void SetValue(IDynamicModelBase model, string name, object value)
        {
            if (this.IndexOf(name) >= 0)
            {
                model.SetValue(this.IndexOf(name), value);
            }
        }

        public IDynamicModelBase Clone(IDynamicModelBase model)
        {
            var item = _factory.Create();

            foreach (var kv in this.ModelMeta.Properties)
            {
                var value = model.GetValue(kv.Index);

                item.SetValue(kv.Index, value);
            }

            return item;
        }

        public bool ValueEquals(IDynamicModelBase model1, IDynamicModelBase model2)
        {
            throw new NotImplementedException();
        }

        public void CopyModel(IDynamicModelBase toModel, IDynamicModelBase fromModel)
        {
            throw new NotImplementedException();
        }

        public object GetValue(object model, string name)
        {
            throw new NotImplementedException();
        }

        public void SetValue(object model, string name, object value)
        {
            throw new NotImplementedException();
        }

        public IDynamicModelBase ToModel(
            IModelEntry<IDynamicModelBase> modelEntry,
            bool current = true)
        {
            var model = _factory.Create();

            foreach (var name in modelEntry.Properties)
            {
                var value = current ? modelEntry.GetCurrentValue(name) :
                                            modelEntry.GetOriginalValue(name);

                this.SetValue(model, name, value);
            }

            return model;
        }
    }
}
